package com.harmontronics.hanma.paas.paas.service;


import com.fasterxml.jackson.databind.ObjectMapper;
import com.harmontronics.hanma.paas.paas.common.CrossDomainFunction;
import com.harmontronics.hanma.paas.paas.consts.EnvEnum;
import com.harmontronics.hanma.paas.paas.domain.app.entity.HmDatasource;
import com.harmontronics.hanma.paas.paas.domain.app.entity.HmDatasourceEnv;
import com.harmontronics.hanma.paas.paas.domain.app.entity.HmProcess;
import com.harmontronics.hanma.paas.paas.domain.app.service.HmProcessService;
import com.harmontronics.hanma.paas.paas.domain.releasesetup.entity.HmReleaseRecord;
import com.harmontronics.hanma.paas.paas.domain.releasesetup.entity.HmReleaseSetup;
import com.harmontronics.hanma.paas.paas.domain.releasesetup.entity.valueobject.I18nKeyEnum;
import com.harmontronics.hanma.paas.paas.domain.releasesetup.service.HmModelUpdateSqlService;
import com.harmontronics.hanma.paas.paas.domain.releasesetup.service.HmReleaseRecordService;
import com.harmontronics.hanma.paas.paas.domain.releasesetup.service.HmReleaseSetupService;
import com.harmontronics.hanma.paas.paas.domain.releasesetup.service.PackService;
import com.harmontronics.hanma.paas.paas.domain.tenant.entity.HmTenantApp;
import com.harmontronics.hanma.paas.paas.domain.tenant.service.HmTenantAppService;
import com.harmontronics.hanma.paas.paas.exception.ErrorKeyException;
import com.harmontronics.hanma.paas.paas.utils.JacksonUtils;
import org.apache.commons.collections.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.List;


@Service("hmReleaseRecordAppService")
public class HmReleaseRecordAppService extends HmReleaseRecordService {

    @Autowired
    PackService packService;
    @Autowired
    private IHmTenantAppService hmTenantAppService;
    @Autowired
    private HmDatasourceAppService hmDatasourceAppService;
    @Autowired
    private HmReleaseSetupService hmReleaseSetupService;
    @Autowired
    private HmProcessService hmProcessService;

    @Autowired
    private HmModelUpdateSqlService hmModelUpdateSqlService;


    public void save(HmReleaseRecord hmReleaseRecord) {
        HmTenantApp hmTenantApp = hmTenantAppService.findByUnique(hmReleaseRecord.getAppUniqueId());
        String appUnique = hmTenantApp.getAppUniqueId();
        EnvEnum setupType = hmReleaseRecord.getSetupType();
        validateEnv(appUnique, setupType);
        Long sequence = packService.getPackSequence(appUnique);
        List<HmProcess> processes = hmProcessService.getAndCheckPublish();
        List<String> sqls = hmModelUpdateSqlService.getSqls(appUnique, sequence);
        CrossDomainFunction function = (Object param) -> {
            File dir = (File) param;
            ObjectMapper objectMapper = JacksonUtils.getObjectMapper();
            for (HmProcess process : processes) {
                String xml = hmProcessService.getProcessDefinitionJson(process);
                try (FileOutputStream xmlOutput = new FileOutputStream(new File(dir, process.getId() + ".xml"));
                     FileOutputStream jsonOutput = new FileOutputStream(new File(dir, process.getId() + ".json"))) {
                    xmlOutput.write(xml.getBytes(StandardCharsets.UTF_8));
                    objectMapper.writerWithDefaultPrettyPrinter().writeValue(jsonOutput, process);
                    hmProcessService.makePacked(process.getId());
                } catch (IOException e) {
                    e.printStackTrace();
                    return false;
                }

            }
            return true;
        };
        super.save(hmReleaseRecord, hmTenantApp.getAppName(), hmTenantApp.getIcon(), sqls, function);
    }

    private void validateEnv(String appUnique, EnvEnum setupType) {
        //验证测试环境和正式环境
        if (!setupType.equals(EnvEnum.DEV)) {
            List<HmDatasource> hmDatasourceList = hmDatasourceAppService.getAllBySetupType(setupType);
            if (CollectionUtils.isEmpty(hmDatasourceList)) {
                throw new ErrorKeyException(I18nKeyEnum.DATASOURCE_SETUP_NOT_EXIST);
            } else {
                for (HmDatasource hmDatasource : hmDatasourceList) {
                    List<HmDatasourceEnv> datasourceEnvList = hmDatasource.getEnvList();
                    if (CollectionUtils.isEmpty(datasourceEnvList)) {
                        if (setupType.equals(EnvEnum.TEST)) {
                            throw new ErrorKeyException(I18nKeyEnum.DATASOURCE_TEST_ENV_NOT_EXIST);
                        } else {
                            throw new ErrorKeyException(I18nKeyEnum.DATASOURCE_PROD_ENV_NOT_EXIST);
                        }
                    }
                }

            }

            List<HmReleaseSetup> releaseSetupList = hmReleaseSetupService.getSetupBySetupType(appUnique, setupType);
            if (CollectionUtils.isEmpty(releaseSetupList)) {
                if (setupType.equals(EnvEnum.TEST)) {
                    throw new ErrorKeyException(I18nKeyEnum.SETUP_TEST_ENV_NOT_EXIST);
                } else {
                    throw new ErrorKeyException(I18nKeyEnum.SETUP_PROD_ENV_NOT_EXIST);
                }
            }
        }
    }
}